package com.cherry.i18n.config;


import com.cherry.i18n.cache.I18nMessageLocalCache;
import com.cherry.i18n.config.properties.I18nProperties;
import com.cherry.i18n.core.I18nMessageSource;
import com.cherry.i18n.core.CherryAcceptHeaderLocaleResolver;
import com.cherry.i18n.provider.I18nMessageProvider;
import com.cherry.i18n.response.I18nResponseAdvice;
import com.cherry.i18n.service.I18nService;
import com.cherry.i18n.service.impl.I18nServiceImpl;
import com.cherry.i18n.util.I18nUtil;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.HierarchicalMessageSource;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.web.servlet.LocaleResolver;

import java.util.Locale;

/**
 * 国际化自动配置
 *
 * @author sinbad.cheng
 * @since 2021-11-11
 */
@Configuration
@EnableConfigurationProperties(I18nProperties.class)
@ConditionalOnProperty(prefix = I18nProperties.PREFIX, name = "enable", havingValue = "true")
public class I18nAutoConfiguration {

    private final I18nProperties i18nProperties;
    private final MessageSource messageSource;

    public I18nAutoConfiguration(I18nProperties i18nProperties, @Qualifier(AbstractApplicationContext.MESSAGE_SOURCE_BEAN_NAME) MessageSource messageSource) {
        this.i18nProperties = i18nProperties;
        this.messageSource = messageSource;
        initDefaultLocale(i18nProperties.getDefaultLocale());
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean(I18nMessageProvider.class)
    public I18nMessageLocalCache i18nMessageLocalCache() {
        return new I18nMessageLocalCache(i18nProperties);
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean(I18nMessageProvider.class)
    public I18nMessageSource i18nMessageSource(I18nMessageProvider i18nMessageProvider,
                                               I18nMessageLocalCache i18nMessageLocalCache) {
        I18nMessageSource i18nMessageSource = new I18nMessageSource(i18nMessageProvider, i18nMessageLocalCache);
        if (messageSource != null && messageSource instanceof HierarchicalMessageSource) {
            HierarchicalMessageSource hms = (HierarchicalMessageSource) messageSource;
            hms.setParentMessageSource(i18nMessageSource);
        }
        return i18nMessageSource;
    }

    @Bean
    @ConditionalOnMissingBean
    public I18nService i18nService(MessageSource messageSource) {
        return new I18nServiceImpl(messageSource);
    }

    @Bean
    public I18nUtil i18nUtil(I18nService i18nService) {
        return new I18nUtil(i18nService);
    }

    @Bean
    @ConditionalOnProperty(prefix = I18nProperties.PREFIX, name = "enable-response-advice", havingValue = "true", matchIfMissing = true)
    public I18nResponseAdvice i18nResponseAdvice(I18nService i18nService, I18nProperties i18nProperties) {
        return new I18nResponseAdvice(i18nService, i18nProperties);
    }

    @Bean
    @ConditionalOnMissingBean
    public LocaleResolver localeResolver() {
        return new CherryAcceptHeaderLocaleResolver(i18nProperties);
    }

    /**
     * 初始化默认区域
     *
     * @param defaultLocale 默认区域
     */
    private void initDefaultLocale(Locale defaultLocale) {
        if (defaultLocale != null) {
            Locale.setDefault(defaultLocale);
            LocaleContextHolder.setDefaultLocale(defaultLocale);
        }
    }

}